import * as CANNON from "cannon-es";
import * as THREE from "three";

/**
 * THREE网格对象转CannonJS刚体
 * @param mesh 
 * @param mass 
 * @returns 
 */
export const geometryToBody = (mesh: THREE.Mesh, mass: number = 0, material: CANNON.Material) => {
    const geometry = mesh.geometry;
    // 顶点索引数组
    const indices = geometry?.index?.array || [];
    // 顶点坐标数组
    const vertices = geometry.getAttribute("position").array || [];
    // 缩放
    const scale = mesh.getWorldScale(new THREE.Vector3());
    // 位置
    const position = mesh.getWorldPosition(new THREE.Vector3());
    // 旋转（四元数）
    const quaternion = mesh.getWorldQuaternion(new THREE.Quaternion());
    const shape = new CANNON.Trimesh(Array.from(vertices), Array.from(indices));
    shape.scale.set(scale.x, scale.y, scale.z);
    const body = new CANNON.Body({
        mass,
        shape,
        material: material || new CANNON.Material()
    })
    body.position.set(position.x, position.y, position.z);
    body.quaternion.set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
    return body;
};

/**
 * THREE网格对象转CannonJS刚体
 * @param mesh 
 * @param mass 
 * @returns 
 */
export const geometryToBody2 = (mesh: THREE.Mesh, mass: number = 0, material: CANNON.Material) => {
    const geometry = mesh.geometry;
    // 顶点索引数组
    const indices = geometry?.index?.array || [];
    // 顶点坐标数组
    const pos = geometry.getAttribute("position");
    // 缩放
    const scale = mesh.getWorldScale(new THREE.Vector3());
    // 位置
    const position = mesh.getWorldPosition(new THREE.Vector3());
    // 旋转（四元数）
    const quaternion = mesh.getWorldQuaternion(new THREE.Quaternion());

    const vertices = [];//所有三角形顶点位置数据
    const faces = [];//所有三角形面的索引值
    for (let i = 0; i < pos.count; i++) {
        const x = pos.getX(i)*scale.x;
        const y = pos.getY(i)*scale.y;
        const z = pos.getZ(i)*scale.z;
        vertices.push(new CANNON.Vec3(x, y, z));
    }
    for (let i = 0; i < indices.length; i += 3) {
        const a = indices[i];
        const b = indices[i + 1];
        const c = indices[i + 2];
        faces.push([a, b, c]);
    }
    // CannonJS的凸多面体ConvexPolyhedron
    const shape = new CANNON.ConvexPolyhedron({ vertices, faces });
    const body = new CANNON.Body({
        mass,
        shape,
        material: material || new CANNON.Material()
    })
    body.position.set(position.x, position.y, position.z);
    body.quaternion.set(quaternion.x, quaternion.y, quaternion.z, quaternion.w);
    return body;
};


export const CapsuleHelper = (R: number, H: number) => {
    const group = new THREE.Group();
    const material = new THREE.MeshLambertMaterial({
        color: 0x00ffff,
        transparent: true,
        opacity: 0.5,
    });
    // 底部半球
    const geometry = new THREE.SphereGeometry(R, 25, 25, 0, 2 * Math.PI, 0, Math.PI / 2);
    geometry.rotateX(Math.PI);
    const mesh = new THREE.Mesh(geometry, material);
    mesh.position.y = R;
    group.add(mesh)
    // 顶部半球
    const geometry2 = new THREE.SphereGeometry(R, 25, 25, 0, 2 * Math.PI, 0, Math.PI / 2);
    const mesh2 = new THREE.Mesh(geometry2, material);
    mesh2.position.set(0, H - R, 0)
    group.add(mesh2)
    // 中间圆柱
    const h = H - 2 * R
    const geometry3 = new THREE.CylinderGeometry(R, R, h, 32, 1, true);
    geometry3.translate(0, h / 2 + R, 0)
    const mesh3 = new THREE.Mesh(geometry3, material);
    group.add(mesh3)
    return group;
}